<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Sprite对象</title>
</head>

<body>

    <canvas id="cvs" width="800" height="500"></canvas>

    <script>
    var cvsEl = document.getElementById('cvs');
    var ctx = cvsEl.getContext('2d'); // canvas渲染上下文

    // 创建一个Image标签。在Image标签加载完成之后，再执行主要代码段。
    var image = new Image();
    image.src = './estell.png';
    image.addEventListener('load', function () {


        /**
         *  精灵对象。
         *  封装了一个自带帧动画的精灵。
         *  将精灵绘制到屏幕上，需要定时调用精灵对象的：
         *      update函数，更新精灵对象的各种状态。
         *      render函数，将精灵绘制到canvas上
         * @param x 精灵的x轴坐标
         * @param y 精灵的y轴坐标
         * @param w 精灵的宽度
         * @param h 精灵的高度
         * @param image 精灵的图像标签
         * @param ctx 渲染上下文
         * @constructor
         */
        function Sprite(x, y, w, h, image, ctx) {
            this.frameIndex = 0; // 当前显示的帧
            this.direction = 0; // 小人的朝向
            this.x = x;
            this.y = y;
            this.w = w;
            this.h = h;
            this.image = image;
            this.ctx = ctx;
        }

        // 渲染函数：把精灵对象绘制到屏幕上
        Sprite.prototype.render = function () {
            this.ctx.drawImage(this.image,
                    this.frameIndex * 256, this.direction * 256, 256, 256,
                    this.x, this.y, this.w, this.h
            )
        };

        // 更新函数：根据间隔时间更新精灵的各种数据
        Sprite.prototype.update = function (dt) {
            this.frameIndex = this.frameIndex >= 7
                    ? 0
                    : this.frameIndex + 1;
        };

        var estell = new Sprite(0, 0, 256, 256, image, ctx);
        estell.direction = 4;

        setInterval(function () {
            ctx.clearRect(0, 0, 800, 500);
            // 先更新精灵的各种数据，再绘制精灵到canvas上
            estell.update();
            estell.render();
        }, 200);
    })
</script>
</body>

</html>